﻿#pragma execution_character_set("utf-8")
#include "communication.h"
#include "ui_communication.h"

CommunicationItem* Communication::lastItem=nullptr;

Communication::Communication(HttpClient* httpClient,WebSocketClient* webSocketClient,FileOperator* fileOperator,SQLiteUtil* sQLiteUtil,QString email,QWidget *parent) :
    QWidget(parent),
    httpClient(httpClient),
    webSocketClient(webSocketClient),
    fileOperator(fileOperator),
    sQLiteUtil(sQLiteUtil),
    dialog(new QSendFileDialog(this)),
    email(email),
    ui(new Ui::Communication)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_DeleteOnClose);//窗口close后释放内存
    setWindowFlags(Qt::FramelessWindowHint);    //隐藏标题栏（无边框）
    setAttribute(Qt::WA_StyledBackground);    //启用样式背景绘制
    setAttribute(Qt::WA_TranslucentBackground);    //背景透明
    setAttribute(Qt::WA_Hover);

    ui->info_SWT->resize(QApplication::primaryScreen()->size());
    ui->widget_6->resize(QApplication::primaryScreen()->size());

    //处理完成的http请求
    loadHttpComponentRespond();
    //处理WebSocket收到消息
    loadSocketComponentRespond();
    //处理用户的交互
    loadBaseComponentRespond();

    createShadow();
}

Communication::~Communication()
{
    delete ui;
}

bool Communication::event(QEvent *event)
{
    if (event->type() == QEvent::HoverMove) {
        QHoverEvent *hoverEvent = static_cast<QHoverEvent *>(event);
        QMouseEvent mouseEvent(QEvent::MouseMove, hoverEvent->pos(),
                               Qt::NoButton, Qt::NoButton, Qt::NoModifier);
        mouseMoveEvent(&mouseEvent);
    }

    return QWidget::event(event);
}

void Communication::leaveEvent(QEvent *event)//鼠标离开窗口时触发
{
    m_bIsPressed = false;
    m_bIsResizing = false;
    QWidget::leaveEvent(event);
}

void Communication::mousePressEvent(QMouseEvent *event)//鼠标在窗口按压时触发
{
    if (event->button() == Qt::LeftButton) {
        m_bIsPressed = true;
        m_pressPoint = event->globalPos();//记录鼠标按压时在桌面的位置
    }

    return QWidget::mousePressEvent(event);
}

void Communication::mouseMoveEvent(QMouseEvent *event)//鼠标在窗口移动时触发
{
    if (windowState() != Qt::WindowMaximized) {
        if (m_bIsPressed) {
            if (m_bIsResizing) {//调整窗口大小
                m_movePoint = event->globalPos() - m_pressPoint;//获取鼠标位置相对鼠标按压位置的移动量
                m_pressPoint+=m_movePoint;//按压位置追踪鼠标

            } else {//移动窗口
                QPoint point = event->globalPos() - m_pressPoint;
                move(pos() + point);
                m_pressPoint = event->globalPos();
            }
        }
        updateRegion(event);
    }
    QWidget::mouseMoveEvent(event);
}

void Communication::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        m_bIsPressed = false;
        m_bIsResizing = false;
    }
    QWidget::mouseReleaseEvent(event);
}

void Communication::updateRegion(QMouseEvent *event)
{
    QRect mainRect = geometry();//获取当前窗口的几何信息（位置和大小）。

    //计算出鼠标指针相对于窗口四个边的距离
    int marginTop = event->globalY() - mainRect.y();//获取鼠标离上边框的距离
    int marginBottom = mainRect.y() + mainRect.height() - event->globalY();//获取鼠标离下边框的距离
    int marginLeft = event->globalX() - mainRect.x();//获取鼠标离左边框的距离
    int marginRight = mainRect.x() + mainRect.width() - event->globalX();//获取鼠标离右边框的距离

    //设置鼠标在窗口的边界时的鼠标指针的变化
    if (!m_bIsResizing) {
        if ( (marginRight >= MARGIN_MIN_SIZE && marginRight <= MARGIN_MAX_SIZE)
            && ((marginBottom <= MARGIN_MAX_SIZE) && marginBottom >= MARGIN_MIN_SIZE) ) {
            m_direction = Direction::BOTTOMRIGHT;//右下
            setCursor(Qt::SizeFDiagCursor);
        } else if ( (marginTop >= MARGIN_MIN_SIZE && marginTop <= MARGIN_MAX_SIZE)
                   && (marginRight >= MARGIN_MIN_SIZE && marginRight <= MARGIN_MAX_SIZE)) {
            m_direction = Direction::TOPRIGHT;//右上
            setCursor(Qt::SizeBDiagCursor);
        } else if ( (marginLeft >= MARGIN_MIN_SIZE && marginLeft <= MARGIN_MAX_SIZE)
                   && (marginTop >= MARGIN_MIN_SIZE && marginTop <= MARGIN_MAX_SIZE) ) {
            m_direction = Direction::TOPLEFT;//左上
            setCursor(Qt::SizeFDiagCursor);
        } else if ( (marginLeft >= MARGIN_MIN_SIZE && marginLeft <= MARGIN_MAX_SIZE)
                   && (marginBottom >= MARGIN_MIN_SIZE && marginBottom <= MARGIN_MAX_SIZE)) {
            m_direction = Direction::BOTTOMLEFT;//左下
            setCursor(Qt::SizeBDiagCursor);
        } else if (marginBottom <= MARGIN_MAX_SIZE && marginBottom >= MARGIN_MIN_SIZE) {
            m_direction = Direction::DOWN;//下
            setCursor(Qt::SizeVerCursor);
        } else if (marginLeft <= MARGIN_MAX_SIZE - 1 && marginLeft >= MARGIN_MIN_SIZE - 1) {
            m_direction = Direction::LEFT;//左
            setCursor(Qt::SizeHorCursor);
        } else if (marginRight <= MARGIN_MAX_SIZE && marginRight >= MARGIN_MIN_SIZE) {
            m_direction = Direction::RIGHT;//右
            setCursor(Qt::SizeHorCursor);
        } else if (marginTop <= MARGIN_MAX_SIZE && marginTop >= MARGIN_MIN_SIZE) {
            m_direction = Direction::UP;//上
            setCursor(Qt::SizeVerCursor);
        } else {//鼠标指针不在窗口的边界,那么鼠标指针恢复默认
            if (!m_bIsPressed) {
                setCursor(Qt::ArrowCursor);
            }
        }
    }

    if (m_direction!=Direction::NONE) {
        m_bIsResizing = true;
        resizeRegion();
    }
}

void Communication::resizeRegion()
{
    if(!m_bIsPressed){
        m_bIsResizing = false;
        m_direction = Direction::NONE;
        return ;
    }
    QRect rect = geometry();
    switch (m_direction)
    {
    case Direction::BOTTOMRIGHT://右下
    {
        extendRight(rect);
        extendDown(rect);
    }
    break;
    case Direction::TOPRIGHT://右上
    {
        extendRight(rect);
        extendTop(rect);
    }
    break;
    case Direction::TOPLEFT://左上
    {
        extendLeft(rect);
        extendTop(rect);
    }
    break;
    case Direction::BOTTOMLEFT://左下
    {
        extendLeft(rect);
        extendDown(rect);
    }
    break;
    case Direction::RIGHT://右
    {
        extendRight(rect);
    }
    break;
    case Direction::DOWN://下
    {
        extendDown(rect);
    }
    break;
    case Direction::LEFT://左
    {
        extendLeft(rect);
    }
    break;
    case Direction::UP://上
    {
        extendTop(rect);
    }
    }
    rect.setWidth(qBound(minimumWidth(), rect.width(), maximumWidth()));
    rect.setHeight(qBound(minimumHeight(), rect.height(), maximumHeight()));
    setGeometry(rect);
}

void Communication::extendLeft(QRect &rect){
    int x=m_pressPoint.x();
    if(x<rect.x()&&rect.width()>=minimumWidth()&&rect.width()<maximumWidth()){
        rect.adjust(m_movePoint.x(), 0, 0, 0);
    }//展开
    else if(x>rect.x()&&rect.width()>minimumWidth()&&rect.width()<=maximumWidth()){
        rect.adjust(m_movePoint.x(), 0, 0, 0);
    }//压缩
}

void Communication::extendRight(QRect &rect){
    int x=m_pressPoint.x();
    if(x>rect.x()+minimumWidth()&&rect.width()>=minimumWidth()&&rect.width()<maximumWidth()){
        rect.adjust(0, 0, m_movePoint.x(), 0);
    }//展开
    else if(x<rect.x()+maximumWidth()&&rect.width()>minimumWidth()&&rect.width()<=maximumWidth()){
        rect.adjust(0, 0, m_movePoint.x(), 0);
    }//压缩
}

void Communication::extendTop(QRect &rect){
    int y=m_pressPoint.y();
    if(y<rect.y()&&rect.height()>=minimumHeight()&&rect.height()<maximumHeight()){
        rect.adjust(0, m_movePoint.y(), 0, 0);
    }//展开
    else if(y>rect.y()&&rect.height()>minimumHeight()&&rect.height()<=maximumHeight()){
        rect.adjust(0, m_movePoint.y(), 0, 0);
    }//压缩
}

void Communication::extendDown(QRect &rect){
    int y=m_pressPoint.y();
    if(y>rect.y()+minimumHeight()&&rect.height()>=minimumHeight()&&rect.height()<maximumHeight()){
        rect.adjust(0, 0, 0, m_movePoint.y());
    }//展开
    else if(y<rect.y()+maximumHeight()&&rect.height()>minimumHeight()&&rect.height()<=maximumHeight()){
        rect.adjust(0, 0, 0, m_movePoint.y());
    }//压缩
}

void Communication::createShadow(){
    QGraphicsDropShadowEffect *mainShadow = new QGraphicsDropShadowEffect(this);
    mainShadow->setOffset(0,0); // 设置阴影偏移量
    mainShadow->setBlurRadius(13); // 设置阴影模糊半径
    mainShadow->setColor(QColor(130,130,130)); // 设置阴影颜色（RGBA）
    ui->Communication_content->setGraphicsEffect(mainShadow);
}

void Communication::keyPressEvent(QKeyEvent* event){
    if(event->key()==Qt::Key_Enter){
        ui->send_BT->clicked();
    }
}

void Communication::loadHttpComponentRespond(){
    connect(httpClient,&HttpClient::finished,[this](const QUrl &url, const QByteArray &data){
        QString URL=url.toString();
        if(URL.contains("upload"))// http://127.0.0.1:10400/App/upload?type=image&&email=%1 email表示自己的账号
        {//上传文件完成更新状态
            QVariantList list=this->fileOperator->parseJsonArray(data);
            for(const QVariant& variant:list){
                QString msgId=variant.toString();
                if (!msgId.isEmpty()) {
                    QVariantMap map;
                    map["isSend"]="isSend+2";
                    sQLiteUtil->updateMessage(map,msgId);//更新状态
                    {
                        //发送信息
                        QVariantMap resultMap=sQLiteUtil->selectOneSelfInfo(msgId);
                        resultMap["msgId"]=msgId;
                        resultMap["receiver"]=resultMap["friendId"];
                        resultMap.remove("friendId");
                        resultMap["sender"]=this->email;
                        httpClient->sendTextMsg(toJson(resultMap));
                    }
                }
            }
        }
        else if(URL.contains("download"))// http://127.0.0.1:10400/App/download?type=image&&email=%1&&fileName=%2&&suffix=%3   email表示给你发图片的对象,name表示图片的名称或信息的ID
        {
            QMap<QString,QString> urlMap=fileOperator->getQueryParamsFromUrl(URL,"&&");
            //更新状态
            {
                QVariantMap map=sQLiteUtil->selectOneMessageIsSend(urlMap["fileName"]);
                if(map["isSend"].toInt()==0||map["isSend"].toInt()==1)
                {
                    map["isSend"]="isSend+2";
                    sQLiteUtil->updateMessage(map,urlMap["fileName"]);
                }
            }

            QString subPath;
            if(urlMap["email"]==this->email)
                subPath=urlMap["email"]+"/Res";
            else
                subPath="Res/"+urlMap["email"];

            QString msgId=urlMap["fileName"];
            {
                QVariantMap map=sQLiteUtil->selectOneMessageContent(urlMap["fileName"]);
                if(!map["content"].toString().isEmpty()){
                    urlMap["fileName"]=map["content"].toString();
                }
            }

            QString path=QString("./accountData/%1/%2/%3.%4").arg(subPath).arg(urlMap["type"]+"Res").arg(urlMap["fileName"]).arg(urlMap["suffix"]);
            //防止重名覆盖
            for(int i=1;QFile::exists(path);i++){
                path=QString("./accountData/Res/%1/%2/%3(%4).%5").arg(urlMap["email"]).arg(urlMap["type"]+"Res").arg(urlMap["fileName"]).arg(i).arg(urlMap["suffix"]);
            }
            if(!data.isEmpty())
                fileOperator->writeFile(path,data);
            emit receiveFileFinish(this,msgId);//发送文件下载完成的信号
        }
    });
}

void Communication::loadSocketComponentRespond(){
    connect(webSocketClient,&WebSocketClient::sigRecvTextMsg,[this](const QString &data){
        QVariantMap msgMap=fileOperator->parseJsonObject(data.toUtf8());
        if(!msgMap.isEmpty()){
            if(msgMap.contains("msgId"))
            {
                //处理收到的好友信息
                //msgId,sender,receiver,type,content,createTime;
                QString sender=msgMap["sender"].toString();
                msgMap.remove("sender");
                msgMap.remove("receiver");
                msgMap["isSelf"]=0;
                msgMap["isSend"]=1;
                sQLiteUtil->insertMessage(msgMap);//将信息插入数据库中msgId,isSelf,isSend,type,content,createTime;
                msgMap.remove("isSelf");
                msgMap.remove("isSend");
                {
                    QVariantMap insertMap;
                    insertMap["msgId"]=msgMap["msgId"];
                    insertMap["friendId"]=sender;
                    sQLiteUtil->insertSession(insertMap);//将信息插入数据库中
                }
                if(msgMap["type"]=="png"){//处理图片
                    httpClient->downLoadFile(QString("/App/download?type=image&&email=%2&&fileName=%3&&suffix=%4").arg(sender).arg(msgMap["msgId"].toString()).arg(msgMap["type"].toString()));//发送http请求下载图片
                }
                if(this->isVisible()){//如果此页面显示
                    CommunicationItem* item=findItem(sender);
                    if(item!=nullptr){
                        //更新数据
                        updateItemInfo(item,msgMap);

                        //显示数据
                        CommunicationPage* page=(CommunicationPage*)item->getPage();
                        OtherInfo* otherInfo=new OtherInfo(sender,item->getUsername(),msgMap);//msgId,type,content,createTime;
                        {//设置时间
                            qint64 currentTime=msgMap["createTime"].toLongLong();
                            if(currentTime-page->getLastTime()>5*60*1000){
                                otherInfo->insertTimeInfo(fileOperator->formatMessageTime(currentTime));
                            }
                            page->setLastTime(currentTime);
                        }
                        if(msgMap["type"].toString()=="png"){//处理图片
                            connect(this,&Communication::receiveFileFinish,otherInfo,&OtherInfo::updateImage);//当图片下载完成时触发
                        }
                        else{//处理文件
                            connect(otherInfo,&OtherInfo::downLoadFile,this,&Communication::downLoadFile);
                            connect(this,&Communication::receiveFileFinish,otherInfo,&OtherInfo::updateFile);
                        }
                        page->insertInfoItem(otherInfo);
                    }
                }
            }
        }
    });
}

void Communication::loadBaseComponentRespond(){
    connect(ui->minimize_BT,&QPushButton::clicked,[this](){
        if(this->isMaximized()){
            this->isMax=true;
        }
        else{
            this->isMax=false;
        }
        this->showMinimized();
    });
    connect(ui->maximize_BT,&QPushButton::clicked,[this](){
        if(this->isMaximized()){
            setNormalStatus();
            setNormalStyle();
        }
        else{
            setMaxStatus();
            setMaximizeStyle();
        }
    });
    connect(ui->close_BT,&QPushButton::clicked,[this](){
        if(this->isMaximized()){
            setNormalStatus();
        }
        while(ui->info_SWT->count())
        {
            ui->shutdown_BT->clicked();
        }
        this->hide();
    });

    connect(ui->shutdown_BT,&QPushButton::clicked,[this](){
        //删除当前聊天页面和绑定的聊天对象
        CommunicationPage* currentPage=(CommunicationPage*)ui->info_SWT->currentWidget();
        CommunicationItem* item=(CommunicationItem*)currentPage->getItem();
        QLayout* friendList=ui->friendList_WT->layout();

        if(item==lastItem){
            lastItem=nullptr;
        }

        if(friendList->count()-1>=2){//item项大于等于2时
            CommunicationItem* endItem=(CommunicationItem*)friendList->itemAt(friendList->count()-2)->widget();//获取最后一个item的地址
            if(endItem==item){//删除最后一个item
                item->deleteLater();
                ui->info_SWT->removeWidget(currentPage);
                currentPage->deleteLater();
                endItem=(CommunicationItem*)friendList->itemAt(friendList->count()-2)->widget();
                endItem->clicked(endItem,endItem->getPage());
            }
            else
            {
                for(int i=0;i<friendList->count()-1;i++){
                    CommunicationItem* currentItem=(CommunicationItem*)friendList->itemAt(i)->widget();
                    if(currentItem==item){
                        item->deleteLater();
                        ui->info_SWT->removeWidget(currentPage);
                        currentPage->deleteLater();
                        currentItem=(CommunicationItem*)friendList->itemAt(i)->widget();
                        currentItem->clicked(currentItem,currentItem->getPage());
                        break;
                    }
                }
            }
        }
        else{//item项小于2时
            delete item;
            ui->info_SWT->removeWidget(currentPage);
            emit hideComm();
        }
    });

    //发送信息
    connect(ui->send_BT,&QPushButton::clicked,[this](){
        CommunicationPage* currentPage=qobject_cast<CommunicationPage*>(ui->info_SWT->currentWidget());
        CommunicationItem* currentItem=qobject_cast<CommunicationItem*>(currentPage->getItem());

        QTextDocument *doc = ui->textEdit->document();
        QTextCursor cursor(doc);
        cursor.movePosition(QTextCursor::Start);
        QTextBlock beforeBlock = doc->firstBlock();

        // 遍历所有块
        QVariantMap map;
        while (beforeBlock.isValid())
        {
            // 遍历块中的每个片段，划分文字和图片
            for (QTextBlock::iterator it = beforeBlock.begin(); !(it.atEnd()); ++it)
            {
                map["msgId"]=QUuid::createUuid().toString(QUuid::WithoutBraces).replace("-","");//获取信息的uuid,设置map的msgId值
                QTextFragment fragment = it.fragment();
                QString receiver=currentItem->getEmail();
                setCreateTime(map);//设置map的createTime值
                if (fragment.charFormat().isImageFormat()){//处理图片
                    QNetworkReply* reply=handleImage(fragment.charFormat().toImageFormat(),map);//设置map的type和content的值
                    showMessage(currentPage,map,reply);//显示消息msgId,type,content,createTime
                    saveMessage(receiver,map);//将信息保存在数据库中
                }
                else//处理文字
                {
                    map["sender"]=this->email;//设置消息的发送者
                    map["receiver"]=receiver;//设置消息的接收者
                    QNetworkReply *reply=handleText(fragment,map);//设置map的type和content的值
                    map.remove("sender");
                    map.remove("receiver");
                    showMessage(currentPage,map,reply);//显示消息msgId,type,content
                    saveMessage(receiver,map);//将信息保存在数据库中
                }
            }
            beforeBlock=beforeBlock.next();
        }
        updateItemInfo(currentItem,map);
        ui->textEdit->clear();// 清除文本编辑区
        ui->textEdit->setFocus();// 设置焦点
    });

    connect(ui->textEdit,&TextEdit::upLoadFile,[this](const QString &filePath){
        CommunicationPage* currentPage=(CommunicationPage*)ui->info_SWT->currentWidget();
        CommunicationItem* currentItem=(CommunicationItem*)currentPage->getItem();
        this->dialog->setCurrentObject(currentItem->getEmail(),currentItem->getUsername());
        this->dialog->addFile(filePath);
        this->dialog->show();
    });

    //发送文件
    connect(this->dialog,&QSendFileDialog::sendFile,[this](const QString &email,QList<QString> fileList){
        CommunicationPage* page=(CommunicationPage*)ui->info_SWT->currentWidget();
        CommunicationItem* item=(CommunicationItem*)page->getItem();
        if(item->getEmail()==email){
            uploadMultiFile(item,page,fileList);
        }
        else{
            item=findItem(email);
            if(item!=nullptr){
                page=(CommunicationPage*)item->getPage();
                uploadMultiFile(item,page,fileList);
                itemClicked(item,page);
            }
            else
            {
                {
                    QVariantMap resultMap=this->sQLiteUtil->selectOneFriendUsername(email);
                    insertFirendList(email,resultMap["userName"].toString(),"[文件]");
                }
                page=(CommunicationPage*)ui->info_SWT->currentWidget();
                uploadMultiFile(item,page,fileList);
            }
        }
    });

    connect(ui->drag_WT,&DragWidget::changShow,[this](){
        if(isMaximized())
        {
            setNormalStatus();
            setNormalStyle();
        }
        else{
            setMaxStatus();
            setMaximizeStyle();
        }
    });

    connect(ui->chooseFile_BT,&QPushButton::clicked,[this](){
        QString desktopPath=QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
        if (desktopPath.isEmpty()) {
            desktopPath = QDir::currentPath();
        }

        QString filePath = QFileDialog::getOpenFileName(this,tr("Open File"), desktopPath,tr("All Files (*);;Text Files (*.txt)"));

        if (!filePath.isEmpty()) {
            ui->textEdit->insertFile(filePath);
        } else {
            qDebug() << "No file selected";
        }
    });
}

void  Communication::setMaximizeStyle(){
    ui->maximize_BT->setStyleSheet(R"(
        QPushButton{
            background-color: transparent;
            border-image:url(':/background/imagesRes/maximize.png');
            border:0px;
        }
        QPushButton:hover{
            background-color:rgba(248, 242, 242, 0.395);
        }
    )");
}
void  Communication::setNormalStyle(){
    ui->maximize_BT->setStyleSheet(R"(
        QPushButton{
            background-color: transparent;
            border-image:url(':/background/imagesRes/normal.png');
            border:0px;
        }
        QPushButton:hover{
            background-color:rgba(248, 242, 242, 0.395);
        }
    )");
}

void Communication::setMaxStatus(){
    ui->verticalLayoutShadow->setContentsMargins(0,0,0,0);
    showMaximized();
}
void Communication::setNormalStatus(){
    ui->verticalLayoutShadow->setContentsMargins(5,5,5,5);
    showNormal();
}

void Communication::insertFirendList(QString email,QString name,QString message){
    QHBoxLayout* friendList=(QHBoxLayout*)ui->friendList_WT->layout();
    //查找有没有email
    CommunicationItem* item=findItem(email);
    if(item!=nullptr)
    {
        item->clicked(item,item->getPage());
        return ;
    }
    //没有email,那么就新建一个
    //新建一个聊天窗口页面
    CommunicationPage* cpage=new CommunicationPage();
    ui->info_SWT->addWidget(cpage);
    //加载数据
    QList<QVariantMap> resultList=sQLiteUtil->selectAllSessionMsg(email);//msgId,isSelf,type,isSend,content,createTime
    for(auto &map:resultList)
    {
        if(map["isSelf"].toBool())
        {//自己发的消息
            SelfInfo* selfInfo=new SelfInfo(this->email,map);//msgId,isSelf,type,isSend,content,createTime
            {//设置时间
                qint64 currentTime=map["createTime"].toLongLong();
                if(currentTime-cpage->getLastTime()>5*60*1000){
                    selfInfo->insertTimeInfo(fileOperator->formatMessageTime(currentTime));
                }
                cpage->setLastTime(currentTime);
            }
            if(map["type"].toString()=="png"){//处理图片
            }
            else//处理文件
                connect(selfInfo,&SelfInfo::downLoadFile,this,&Communication::downLoadFile);
            cpage->appendInfoItem(selfInfo);
        }
        else{//别人发的消息
            OtherInfo* otherInfo=new OtherInfo(email,name,map);//msgId,isSelf,type,isSend,content,createTime
            {//设置时间
                qint64 currentTime=map["createTime"].toLongLong();
                if(currentTime-cpage->getLastTime()>5*60*1000){
                    otherInfo->insertTimeInfo(fileOperator->formatMessageTime(currentTime));
                }
                cpage->setLastTime(currentTime);
            }
            if(map["type"].toString()=="png"){//处理图片
                if(map["isSend"].toInt()!=3)
                    connect(this,&Communication::receiveFileFinish,otherInfo,&OtherInfo::updateImage);
            }
            else//处理文件
            {
                connect(otherInfo,&OtherInfo::downLoadFile,this,&Communication::downLoadFile);
                connect(this,&Communication::receiveFileFinish,otherInfo,&OtherInfo::updateFile);
            }
            cpage->appendInfoItem(otherInfo);
        }
        map.clear();
        resultList.pop_front();
    }
    CommunicationItem* citem=new CommunicationItem(email,name,message,fileOperator->formatMessageTime(cpage->getLastTime()));
    connect(citem,&CommunicationItem::clicked,this,&Communication::itemClicked);
    connect(citem,&CommunicationItem::closeClicked,this,&Communication::closeItem);
    friendList->insertWidget(0,citem);
    //双向绑定页面
    citem->setPage(cpage);
    cpage->setItem(citem);
    //设置当前的聊天页面
    citem->clicked(citem,cpage);
}

CommunicationItem* Communication::findItem(const QString &email){
    QVBoxLayout* friendList=(QVBoxLayout*)ui->friendList_WT->layout();
    for(int i=0;i<friendList->count()-1;i++){
        QWidget *widget=friendList->itemAt(i)->widget();
        if(widget&&dynamic_cast<CommunicationItem*>(widget)){
            CommunicationItem* item=static_cast<CommunicationItem*>(widget);
            if(item->getEmail()==email){
                return item;
            }
        }
    }
    return nullptr;
}

void Communication::itemClicked(CommunicationItem* newItem,QWidget* cpage){
    newItem->setClickedStyle();
    ui->info_SWT->setCurrentWidget(cpage);
    if (lastItem==nullptr)
        lastItem = newItem;
    else if (lastItem != newItem)
    {
        lastItem->setNormalStyle();
        lastItem = newItem;
    }
}

void Communication::closeItem(QWidget* item,QWidget* page){
    if(page==ui->info_SWT->currentWidget())
    {
        ui->shutdown_BT->clicked();
    }
    else
    {
        delete item;
        ui->info_SWT->removeWidget(page);
    }
}

void Communication::updateItemInfo(CommunicationItem* item,QVariantMap &map){
    QString newInfo;
    if(map["type"].toString()=="text"){
        newInfo=map["content"].toString();
    }
    else if(isImage(map["type"].toString())){
        newInfo="[图片]";
    }
    else{
        newInfo="[文件]";
    }
   item->setNewInfo(newInfo,this->fileOperator->formatMessageTime(map["createTime"].toLongLong()));
}

void Communication::addTime(CommunicationPage* page,const qint64 &currentTime){
   if(currentTime-page->getLastTime()>5*60*1000){//距离上一个消息的时间超过5分钟
        TimeInfo* timeInfo=new TimeInfo(fileOperator->formatMessageTime(currentTime));
        page->appendInfoItem(timeInfo);
   }
   page->setLastTime(currentTime);//重新设置page的最后一条消息的时间
}

bool Communication::isImage(const QString &suffix){
   QStringList imageSuffixes = {"jpg", "jpeg", "png", "gif", "bmp", "tiff", "tif", "webp"};
    return imageSuffixes.contains(suffix);
}

void Communication::uploadMultiFile(CommunicationItem* item,CommunicationPage* page,QList<QString> &fileList){
    for(auto &url : fileList){
        QVariantMap map;
        QString targetPath=preventDuplicateFilename(url,map);//设置type,content
        fileOperator->copyFile(url,targetPath);//拷贝文件
        QString uuid=QUuid::createUuid().toString(QUuid::WithoutBraces).replace("-","");//获取信息的uuid
        QNetworkReply* reply=httpClient->upLoadFile(QString("/App/upload?type=file"),targetPath,uuid);//发送http请求上传文件
        //显示数据
        {
            map["msgId"]=uuid;
            qint64 currentTime=QDateTime::currentMSecsSinceEpoch();
            map["createTime"]=currentTime;
            SelfInfo* selfInfo=new SelfInfo(this->email,map,reply);//msgId,type,content,createTime
            if(currentTime-page->getLastTime()>5*60*1000){//设置时间
                selfInfo->insertTimeInfo(fileOperator->formatMessageTime(currentTime));
            }
            page->setLastTime(currentTime);
            connect(selfInfo,&SelfInfo::downLoadFile,this,&Communication::downLoadFile);
            page->insertInfoItem(selfInfo);
            this->dialog->closeClicked();
        }
        updateItemInfo(item,map);//使用type,content
        sQLiteUtil->insertMessage(map);//msgId,type,content,createTime
        map.clear();
        map["msgId"]=uuid;
        map["friendId"]=item->getEmail();
        sQLiteUtil->insertSession(map);//msgId,friendId
    }
}

void Communication::downLoadFile(const QString &msgId){
    QVariantMap resultMap=sQLiteUtil->selectOneMessageType(msgId);
    QString email;
    if(resultMap["isSelf"].toBool())
        email=this->email;
    else
        email=resultMap["friendId"].toString();
    httpClient->post(QString("/App/download?type=file&&email=%1&&fileName=%2&&suffix=%3").arg(email,msgId,resultMap["type"].toString()));
}

QByteArray Communication::toJson(QVariantMap &map){
    QJsonDocument jsonDoc(this->fileOperator->recursiveWriteJsonObject(map));
    return jsonDoc.toJson();
}
QNetworkReply* Communication::handleText(QTextFragment &fragment,QVariantMap &map){
    map["type"]="text";
    map["content"]=fragment.text();
    return httpClient->sendTextMsg(toJson(map));//将信息发给服务器
}

QNetworkReply* Communication::handleImage(const QTextImageFormat &imageFormat,QVariantMap &map){
    QString imagePath=imageFormat.name();
    if (!imagePath.isEmpty()&&QFile::exists(imagePath))
    {
        QString path=QString("./accountData/%1/Res/imageRes/%2.png").arg(this->email,map["msgId"].toString());//图片统一png格式
        fileOperator->copyFile(imagePath,path);//复制图片到应用目录下保存
        map["type"]=QFileInfo(path).suffix();//设置文件的类型
        map["content"]="";
        return httpClient->upLoadFile(QString("/App/upload?type=image"),path,map["msgId"].toString());//上传图片
    }
    return nullptr;
}

void Communication::setCreateTime(QVariantMap &map){
    qint64 currentTime=QDateTime::currentMSecsSinceEpoch();
    if(map["createTime"].toUInt()==currentTime)
        currentTime=currentTime+1;
    map["createTime"]=currentTime;
}

void Communication::showMessage(CommunicationPage* currentPage,QVariantMap &map,QNetworkReply* reply){
    //显示信息
    SelfInfo* infoItem=new SelfInfo(this->email,map,reply);//,createTime
    {//设置时间
        qint64 currentTime=map["createTime"].toULongLong();
        if(currentTime-currentPage->getLastTime()>5*60*1000){
            infoItem->insertTimeInfo(fileOperator->formatMessageTime(currentTime));
        }
        currentPage->setLastTime(currentTime);
    }
    currentPage->insertInfoItem(infoItem);
}

void Communication::saveMessage(const QString &email,QVariantMap &map){
    //插入信息到数据库中
    this->sQLiteUtil->insertMessage(map);
    QVariantMap insertMap;
    insertMap["friendId"]=email;
    insertMap["msgId"]=map["msgId"];
    this->sQLiteUtil->insertSession(insertMap);
}

QString Communication::preventDuplicateFilename(const QString &path,QVariantMap &map){
    QFileInfo originFile(path);
    QString basePath=QString("./accountData/%1/Res/fileRes/").arg(this->email);
    QString fileName=originFile.fileName();
    fileName=fileName.left(fileName.lastIndexOf("."));//获取文件的原名，例如 LinkMate系统的设计与实现
    QString suffix=originFile.suffix();//获取文件的后缀 例如：docx
    QString num="";//重复数量
    qDebug()<<basePath+fileName+num+"."+suffix;
    for(int i=1;QFile::exists(basePath+fileName+num+"."+suffix);i++){
        num=QString("(%1)").arg(i);
    }
    map["type"]=suffix;//文件的类型
    map["content"]=fileName+num;//文件名字,不要后缀
    return basePath+fileName+num+"."+suffix;
}
